﻿using Core.Authorization;
using Core.Domain.Entities;
using Core.Domain.Events;
using Core.Identity.Common.Interfaces.Common.Interfaces;
using Core.Models;
using Mapster;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Core.Tenant.Features.AssignPermission;

/// <summary>
/// 分配权限
/// </summary>
public class AssignPermissionToTenantCommand : IRequest<Result<bool>>
{
    public required string TenantId { get; set; }
    public List<Guid>? PermissionIds { get; set; }
}

public class AssignPermissionToTenantCommandHandler(
    IIdentityDbContext dbContext,
    IPublisher publisher)
    : IRequestHandler<AssignPermissionToTenantCommand, Result<bool>>
{

    public async Task<Result<bool>> Handle(AssignPermissionToTenantCommand request, CancellationToken cancellationToken)
    {
        if (request.TenantId== TenantConstants.Root.Id)
        {
            throw new BoilerplateException("默认租户禁止操作");
        }
        var tenantPermissionsToArchive = await dbContext.TenantPermissions
            .Where(x => x.BoilerplateTenantInfoId == request.TenantId)
            .ToListAsync();

        var batchId = Guid.CreateVersion7(DateTime.UtcNow);
        if (tenantPermissionsToArchive.Count != 0)
        {
            var historyRecords = tenantPermissionsToArchive.Adapt<List<TenantPermissionHistory>>();
            await dbContext.TenantPermissionHistories.AddRangeAsync(historyRecords);
            dbContext.TenantPermissions.RemoveRange(tenantPermissionsToArchive);
        }

        if (request.PermissionIds != null && request.PermissionIds.Count != 0)
        {
            var newTenantPermissionsToCreate = new List<TenantPermission>();
            foreach (var permissionId in request.PermissionIds)
            {
                var tenantPermission = new TenantPermission()
                {
                    BoilerplateTenantInfoId = request.TenantId,
                    PermissionId = permissionId,
                    AssignmentBatchId = batchId,
                };
                newTenantPermissionsToCreate.Add(tenantPermission);
            }
            await dbContext.TenantPermissions.AddRangeAsync(newTenantPermissionsToCreate);
        }

        await publisher.Publish(new AssignPermissionToTenantEvent(request.TenantId, request.PermissionIds, batchId));

        var result = await dbContext.SaveChangesAsync(cancellationToken) > 0;
        return await Result<bool>.SucceedAsync(result, result, ["操作失败"]);
    }
}
